package com.ws.utils.safeUtil;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class TranSM4Utils {
	
	/**
	 * 
	 * @param plainText
	 * @param secretKey
	 * @param iv
	 * @return
	 */
	public static String encryptData_CBC(
			String plainText, 
			String secretKey,
			String iv
			) {
		return encryptData_CBC(plainText, secretKey, iv, false);
	}

	/**
	 * 
	 * @param cipherText
	 * @param secretKey
	 * @param iv
	 * @return
	 */
	public static String decryptData_CBC(
			String cipherText,
			String secretKey,
			String iv
	) {
		return decryptData_CBC(cipherText, secretKey, iv, false);
	}

	private static String encryptData_CBC(
			String plainText, 
			String secretKey,
			String iv, 
			boolean hexString
	) {
		try {
			SM4_Context ctx = new SM4_Context();
			ctx.isPadding = true;
			ctx.mode = SM4.SM4_ENCRYPT;

			byte[] keyBytes;
			byte[] ivBytes;
			if (hexString) {
				keyBytes = Util.hexStringToBytes(secretKey);
				ivBytes = Util.hexStringToBytes(iv);
			} else {
				keyBytes = secretKey.getBytes();
				ivBytes = iv.getBytes();
			}

			SM4 sm4 = new SM4();
			sm4.sm4_setkey_enc(ctx, keyBytes);
			byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes,
					plainText.getBytes("UTF-8"));
			String cipherText = new BASE64Encoder().encode(encrypted);
			if (cipherText != null && cipherText.trim().length() > 0) {
				Pattern p = Pattern.compile("\\s*|\t|\r|\n");
				Matcher m = p.matcher(cipherText);
				cipherText = m.replaceAll("");
			}
			return cipherText;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 
	 * @param cipherText
	 * @param secretKey
	 * @param iv
	 * @param hexString
	 * @return
	 */
	private static String decryptData_CBC(
			String cipherText,
			String secretKey,
			String iv, 
			boolean hexString
	) {
		try {
			SM4_Context ctx = new SM4_Context();
			ctx.isPadding = true;
			ctx.mode = SM4.SM4_DECRYPT;

			byte[] keyBytes;
			byte[] ivBytes;
			if (hexString) {
				keyBytes = Util.hexStringToBytes(secretKey);
				ivBytes = Util.hexStringToBytes(iv);
			} else {
				keyBytes = secretKey.getBytes();
				ivBytes = iv.getBytes();
			}

			SM4 sm4 = new SM4();
			sm4.sm4_setkey_dec(ctx, keyBytes);
			byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes,
					new BASE64Decoder().decodeBuffer(cipherText));
			return new String(decrypted, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static String encryptData_ECB(
			String plainText, 
			String secretKey,
			String iv
	) {
		return encryptData_ECB(plainText, secretKey, iv, false);
	}
	
	private static String encryptData_ECB(
			String plainText, 
			String secretKey,
			String iv, 
			boolean hexString
	) {
		try {
			SM4_Context ctx = new SM4_Context();
			ctx.isPadding = true;
			ctx.mode = SM4.SM4_ENCRYPT;

			byte[] keyBytes;
			if (hexString) {
				keyBytes = Util.hexStringToBytes(secretKey);
			} else {
				keyBytes = secretKey.getBytes();
			}

			SM4 sm4 = new SM4();
			sm4.sm4_setkey_enc(ctx, keyBytes);
			byte[] encrypted = sm4.sm4_crypt_ecb(ctx,
					plainText.getBytes("UTF-8"));
			String cipherText = new BASE64Encoder().encode(encrypted);
			if (cipherText != null && cipherText.trim().length() > 0) {
				Pattern p = Pattern.compile("\\s*|\t|\r|\n");
				Matcher m = p.matcher(cipherText);
				cipherText = m.replaceAll("");
			}
			return cipherText;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static String decryptData_ECB (
			String cipherText, 
			String secretKey,
			String iv
			) {
		return decryptData_ECB(cipherText, secretKey, iv, false);
	}

	private static String decryptData_ECB (
				String cipherText, 
				String secretKey,
				String iv, 
				boolean hexString
		) {
		try {
			SM4_Context ctx = new SM4_Context();
			ctx.isPadding = true;
			ctx.mode = SM4.SM4_DECRYPT;

			byte[] keyBytes;
			if (hexString) {
				keyBytes = Util.hexStringToBytes(secretKey);
			} else {
				keyBytes = secretKey.getBytes();
			}
			SM4 sm4 = new SM4();
			sm4.sm4_setkey_dec(ctx, keyBytes);
			byte[] decrypted = sm4.sm4_crypt_ecb(ctx,
					new BASE64Decoder().decodeBuffer(cipherText));
			return new String(decrypted, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static void main(String[] args) throws IOException {

		/*String encrypted = "Z3HdMj46d//aT6Y71ah41ndHxskY15gKuTlQLdV3jCkmzBclOx21jDHDdlKX9PGs";
		String key = "2NmmMLXXvkYOhxwg";//
		String iv = "cClMxVoEI9AvR5yw";

		System.out.println(decryptData_CBC(encrypted, key, iv));



		encrypted = "iROA5sQHRDSac8cJocuHV9AYFyJIC8Kn";
		key = "MwaSh4dCgFZcVDuM";//
		iv = "bN33tFhCmA6NYPvS";

		System.out.println(encryptData_CBC(encrypted, key, iv));*/

		String SE_tempKey_encrypted = "OFY1Hw7Eyokqj3T22vs/AEEm68AwQ422n+O79StHu3HQ4qbBI5Ca/OXUjBxTWGfk";
		String key1 = "lLgYEFwJJAlu75sl";
		String iv1 = "eXmr9oU68cDZDr2x";

		String SE_tempKey = TranSM4Utils.decryptData_CBC(SE_tempKey_encrypted,key1, iv1);

		String key = SE_tempKey.substring(0, 16);
		String iv = SE_tempKey.substring(16);


		String json = "{\"itemId\":\"1\",\"versionNum\":0,\"oper\":\"i\",\"content\":{\"ACC_ID\":\"16876\",\"IS_DELETED\":0,\"APPRO_DATA\":\"20201029\",\"END_DATE\":\"20201029\",\"START_DATE\":\"20201029\",\"BANK_ACC_NAME\":\"���Ļ���������ס���ʽ��������\",\"BANK_ACC_NO\":\"106000000000\",\"MOF_DIV_CODE\":\"640000\",\"CREATE_TIME\":\"20201029121000\",\"OPEN_BANK_NAME\":\"�й��������н��֧��\"},\"tableName\":\"BAS_ACCOUNT\"}";
		/*String key = "dFVO1sR8X7vgbTBT";//
		String iv = "hbqFMJSOhPOChbyg";*/

		String ens = encryptData_CBC(json, key, iv);
		System.out.println(ens);

		String encrypted = "bD8dxaSB1IXMULo22ajG4dwhgnI9BchWFgC93ZzAL6ZWBbjO9FmZ9L/XKzIn8iJdvkHN4fmpFUdX8PgOUAgvyui4ZEHQLtFEHf7DwcKged5ld3241h8Hud7DpzjK5383Rsn8rpNN8VxN+UBhwuHF86mlOAwPwvnhghjsACZ+MszR3uHkadzOSuzgIwU7rOQZjg7DjoQUg4R0nuiotxhN4KclWGKe+Q/96Dng+SnL+AX3WQgnKHzwbV2PdFa5AD0UZRwwDHj2hRdXMVeqXMlESs7wjaVvQgNnH2WYhT8Na8FKbzZKzfjnNVtoD5BSoq++7C41to9NREGMWbrj7tcEtXp8FLeYF+7csOLazxakcP2BkSdVriOSC1flNh2tSAwH3KM+hJmzHFMCBPEuHeNyoIxTGjCAVp6QfNwCuYSF8xfKJ7zx3yv0A5LAlcG03Fu/VEQtIy7MGu7tl7mdavqx7tNsrYgD2aB0iWwbJhDvywk=";

		System.out.println(decryptData_CBC(ens, key, iv));

	}
}
